package org.yunai.yfserver.async;

import org.slf4j.Logger;
import org.yunai.yfserver.common.LoggerFactory;
import org.yunai.yfserver.server.IMessageProcessor;
import org.yunai.yfserver.server.NamedThreadFactory;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * IO操作服务实现类
 * User: yunai
 * Date: 13-3-28
 * Time: 下午2:19
 */
public class IoOperationService implements IIoOperationService {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerFactory.Logger.async, IoOperationService.class);

    private final ExecutorService parallelExecutor;
    private final ExecutorService[] serialExecutors;

    private final IMessageProcessor msgProcessor;

    /**
     * 创建IO操作服务
     *
     * @param nThreads 线程数
     */
    public IoOperationService(int nThreads, IMessageProcessor msgProcessor) {
        LOGGER.info("[IoOperationService] [start].");

        this.parallelExecutor = Executors.newFixedThreadPool(nThreads, new NamedThreadFactory(getClass(), "parallel"));
        this.serialExecutors = new ExecutorService[nThreads];
        for (int i = 0; i < nThreads; i++) {
            this.serialExecutors[i] = Executors.newFixedThreadPool(1, new NamedThreadFactory(getClass(), "serial-" + i));
        }
        this.msgProcessor = msgProcessor;

        LOGGER.info("[IoOperationService] [start success].");
    }

    @Override
    public void asyncExecute(IIoOperation operation) {
        // TODO 服务器正在停止

        new AsyncIoOperation(operation, parallelExecutor, msgProcessor).execute();
    }

    @Override
    public void asyncExecute(IIoSerialOperation operation) {
        int serialIndex = operation.getSerialKey() % serialExecutors.length;
        new AsyncIoOperation(operation, serialExecutors[serialIndex], msgProcessor).execute();
    }

    @Override
    public void syncExecute(IIoOperation operation) {
        new SyncIoOperation(operation).execute();
    }

    // TODO 暂时没实现，等一次性实现stop服务
    @Override
    public void stop() {
        //To change body of implemented methods use File | Settings | File Templates.
    }
}
